Skip to content

feat(managed-agents): close five Claude Code agent-config gaps - #4557

Merged
wpfleger96 merged 6 commits into
mainfrom
duncan/claude-config-gaps
Aug 18, 2026
Merged

feat(managed-agents): close five Claude Code agent-config gaps#4557
wpfleger96 merged 6 commits into
mainfrom
duncan/claude-config-gaps

Conversation

@wpfleger96

@wpfleger96 wpfleger96 commented Aug 3, 2026

Copy link
Copy Markdown
Member

Closes five Claude Code agent-config gaps in Buzz Desktop, split into three commits that share the spawn-time and live-switch surfaces.

Config isolation, model authority, and Auto mode (#2692, #2884, #3493)

Thinking effort end-to-end for local Claude agents

Effort flows from the running session's discovered thought_level config option through the config surface to a local-only write control and a read-only two-facts display.

  • Reader. Discovers the thought_level config option from the session cache (never hardcoded) and populates effort_config_id / effort_options on RuntimeConfigSurface. The canonical effort tier orders record env > record.effort_level (BuzzExplicit) > ACP > persona > global > definition > file, so the panel shows the effort the next spawn will launch with while resolve_with_override surfaces the running ACP value as the struck-through override — neither masks the other silently.
  • Write control. persist_agent_effort_level is a direct-write Tauri setter (writes record.effort_level + updated_at, save_managed_agents) that rejects non-local backends — remote effort is set at deploy time via policy_env. EffortPickerField mounts in AgentInstanceEditDialog beside the Model block, gated on a local backend AND a discovered effortConfigId. It persists directly and invalidates the config surface, mirroring the setManagedAgentAutoRestart standalone-setter precedent, so the frozen UpdateManagedAgentInput shape stays frozen.
  • Display. The read-only configured-vs-current two-facts display is the thinkingEffort normalized field in AgentConfigPanel, fed by the reader's canonical tier ordering.
  • buzz-acp applies the startup effort env at session start.

Distinguish a rejected model switch from silent success

A live model switch collapsed adapter rejection into success: apply_model_switch returned Ok on both an accepted switch and an application-level refusal, so the caller cached pre-switch capabilities as if they described the target model and Desktop reported the pick as landed.

  • ModelSwitchOutcome::{Applied(Value),Rejected}. Transport-class errors still propagate as Err (respawn the poisoned stdio); an application-level refusal is now Rejected.
  • The caller drives everything off post_switch_snapshot: Applied refreshes model_capabilities from the target model's echoed configOptions (or drops to None when none are echoed, so a pre-switch snapshot is never mistaken for the target's); Rejected preserves pre-switch caps and emits a failure control_result. Effort resolution and the session-config capture read the post-switch snapshot so they converge on the model the session actually runs; modelOverridden is gated on switch_succeeded.
  • liveSwitchOutcome.ts gains a distinct "failed" outcome for the adapter failure frame and treats the busy-path "sent" ack as provisional — it never counts toward success. Success is confirmed only by a real positive terminal frame (the busy-path deferred apply emits a correlated switched control_result when it lands), and the fallback timeout resolves an honest "pending" (accepted, apply deferred), never a false "ok". ModelPicker surfaces a distinct toast per outcome — failed, unsupported, and pending.

Scope explicitly excluded

Per-agent config dir provisioning, CLAUDE_SECURESTORAGE_CONFIG_DIR sentinel injection, settings.json projection, protected-key stripping, MCP inheritance, spawn serialization, and the last_spawn_warnings surface are absent from this diff. Silent-fallback machinery for non-Claude runtimes (#2265/#4004) is a tracked follow-up.

Sanctioned follow-ups

  • Live mid-conversation effort switching. Effort is spawn-scoped only in this PR: the worker reads BUZZ_ACP_EFFORT_LEVEL once and applies it at session creation. The live effort-switch machinery (mid-conversation effort RPC + ack frame) was deliberately removed and is archived on archive/claude-config-gaps-live-effort for a future plan-gated revival.
  • Idle-path late model-switch rejection is unobservable. An idle switch acks switched immediately after catalog validation, but the real set_config_option runs at the next session creation — potentially much later — so a rejection there is not surfaced back to the picker (holding a subscription that long is not sensible). Pre-existing, catalog-gated behavior; a durable fix is a tracked follow-up.

Closes #2692, #2884, #3493

@wpfleger96
wpfleger96 requested a review from a team as a code owner August 3, 2026 16:25
@wpfleger96 wpfleger96 changed the title feat(managed-agents): isolate Claude Code agent config per-agent root feat(managed-agents): claude config gaps — isolation, model authority, PermissionMode Auto, effort persistence, bridge path fix Aug 3, 2026
@wpfleger96 wpfleger96 changed the title feat(managed-agents): claude config gaps — isolation, model authority, PermissionMode Auto, effort persistence, bridge path fix feat(managed-agents): Claude Code agent config isolation (B1–B8 + A1/A7 + Thufir invariants) Aug 3, 2026
@wpfleger96
wpfleger96 force-pushed the duncan/claude-config-gaps branch 2 times, most recently from 952e5c4 to c1397bf Compare August 4, 2026 23:39
@wpfleger96 wpfleger96 changed the title feat(managed-agents): Claude Code agent config isolation (B1–B8 + A1/A7 + Thufir invariants) fix(managed-agents): apply Claude Code agent config via ACP/env; respect CLAUDE_CONFIG_DIR Aug 4, 2026
wpfleger96 added a commit that referenced this pull request Aug 6, 2026
Add the Auto variant to PermissionMode (wire string 'auto'; #4557 adds the
same variant from the claude-config arc — this commit establishes the
contradiction logic ahead of that merge so the rebase is mechanical).

Auto mode = fully autonomous execution; model-gated (requires
supportsAutoMode); the adapter self-approves all tool calls internally
and never emits session/request_permission.

Mode matrix:
- allow + auto → compatible (transmit as-is; both want unattended approval)
- ask   + auto → startup error (card never fires — ask becomes a dead letter)
- reject + auto → startup error (inverted-security worst case: policy says
                  deny while adapter silently auto-approves everything)

Tests: 4 new pinned tests (allow+auto ok, ask+auto error, reject+auto error,
wire string correct). Total: 724 passing.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>

@kalvinnchau kalvinnchau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Include the request nonce in invalid_value acknowledgements — crates/buzz-acp/src/lib.rs:1320

The validation-rejection branch returns before the common acknowledgement builder adds nonce. Desktop always supplies a nonce and awaitEffortOutcome rejects every acknowledgement whose nonce does not match, so a genuinely invalid selection is ignored until the 8-second timeout and then presented as “Applies at next session,” even though the pool was deliberately left unchanged. Add the incoming nonce to this early acknowledgement (and cover the real nonce-bearing invalid-value path rather than only nonce-free fixtures).

[P2] Seed committed_effort when the startup effort is successfully applied — crates/buzz-acp/src/pool.rs:791

A persisted startup effort is applied by create_session_and_apply_model, but its checkout has desired_effort_gen == None; return_agent copies it into desired_effort and never records it in committed_effort. If the user subsequently selects another valid effort and the adapter rejects/times out, the failure path rolls desired_effort back to committed_effort, which is still None, instead of restoring the previously confirmed startup value. Record a successful startup application as the committed baseline (or initialize the pool baseline from the persisted value once capabilities confirm it), and add a startup-success → live-pick-failure regression.

[P2] Serialize generation resolution across parallel workers — crates/buzz-acp/src/pool.rs:805

Every worker checked out for the same generation independently emits a terminal acknowledgement and independently commits or rolls back the shared pool state. With parallelism >1, if worker B fails and returns first it rolls desired_effort back; if worker A then returns success, it updates only committed_effort and leaves desired_effort rolled back. The observer can persist A's ok, while future checkouts receive the old/default value. The reverse return order produces a different result, so pool state is scheduler-dependent. Resolve each generation once with explicit aggregate semantics (and emit one terminal outcome), or ensure a later same-generation success restores desired_effort consistently; cover both return orders with two workers.

Validation at exact PR HEAD b7c99fb94808cf3b07bb7540121d8eb4513578dd: cargo test -p buzz-acp --lib passed (723 tests); node --test src/features/agents/lib/effortOutcome.test.mjs passed (15 tests). These paths are not covered by the current suite.

@wpfleger96
wpfleger96 force-pushed the duncan/claude-config-gaps branch from 49177be to 756ed48 Compare August 10, 2026 18:27
@wpfleger96
wpfleger96 force-pushed the duncan/claude-config-gaps branch from a4e36e2 to bcff68d Compare August 13, 2026 17:01
@wpfleger96 wpfleger96 changed the title fix(managed-agents): apply Claude Code agent config via ACP/env; respect CLAUDE_CONFIG_DIR feat(managed-agents): close five Claude Code agent-config gaps Aug 13, 2026
@wpfleger96
wpfleger96 force-pushed the duncan/claude-config-gaps branch 5 times, most recently from c3acf91 to b337a4c Compare August 17, 2026 15:53

@kalvinnchau kalvinnchau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Do not treat a switch that never landed as success — desktop/src/features/agents/lib/liveSwitchOutcome.ts:116

Every status other than unsupported_model, failure, and sent falls through to the positive-terminal counter. That includes turn_ending and no_active_turn, but the producer explicitly emits those when it could not deliver the switch: turn_ending means the control oneshot was already consumed, and no_active_turn means neither an in-flight task nor an idle session-owning agent could be found (crates/buzz-acp/src/lib.rs:1355-1377). This race is reachable when activeTurns is stale between the picker snapshot and harness receipt, or when another control signal is already ending the turn. The picker then shows “Model switched for this session” even though desired_model was never set and no later apply will occur; the added test at liveSwitchOutcome.test.mjs:87-100 currently codifies that false success for turn_ending.

Handle statuses exhaustively. Count only switched as an applied terminal; keep sent provisional, and map turn_ending / no_active_turn to an honest non-success outcome (or retry/persist through a path that actually applies the requested model). Add regression rows for both producer statuses.

kalvinnchau
kalvinnchau previously approved these changes Aug 17, 2026

@kalvinnchau kalvinnchau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed exact head e7049b4b6f7c9404205db7a0cb86677aaeaf477c against merge base 439c03749182495ee09f85a73423dd17e7ccda61.

The prior P2 is resolved. liveSwitchOutcome.ts now treats only switched as applied success, leaves sent provisional, maps turn_ending and no_active_turn to not_delivered, and ignores unknown statuses. Regression coverage exercises both non-delivery statuses and future unknown statuses. The subsequent huddle import consolidation is semantics-preserving.

No additional findings. Validation on the exact head: cargo test -p buzz-acp passed (816 library + 9 lifecycle tests); desktop pnpm test passed (5,013 tests); git diff --check clean. GitHub CI remained in progress at review time.

Duncan and others added 5 commits August 18, 2026 14:19
…Auto mode

Three Claude Code agent-config gaps that share the spawn-time env surface:

- #3493: honor a user-set CLAUDE_CONFIG_DIR when reading claude settings.json
  and .claude.json. The claude 2.1.x binary resolves both files relative to
  CLAUDE_CONFIG_DIR (falling back to homedir), so the config panel must read
  from the same directory the agent actually uses. Surfaces a Keychain caveat
  note when a custom dir is active, since a custom config dir maps to a fresh
  Keychain namespace unless CLAUDE_SECURESTORAGE_CONFIG_DIR is also set.

- #2692: ANTHROPIC_MODEL is the single startup model authority for claude.
  Local spawns write ANTHROPIC_MODEL and strip BUZZ_ACP_MODEL so the harness
  never sees two model authorities; remote deploys send ANTHROPIC_MODEL in
  policy_env instead of BUZZ_ACP_MODEL. All non-claude runtimes are unchanged
  and continue to use BUZZ_ACP_MODEL.

- #2884: add PermissionMode::Auto (wire string "auto"). Model-gated and
  degrades to default when the active model does not support it.

Closes #2692
Closes #2884
Closes #3493

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Effort now flows from the running session's discovered `thought_level`
config option through the config surface to a local-only write control and
a read-only two-facts display, closing the effort gap in the Claude
agent-config set.

- Reader discovers the `thought_level` config option from the session cache
  (never hardcoded) and populates `effort_config_id` / `effort_options` on
  RuntimeConfigSurface. The canonical effort tier orders record env >
  record.effort_level (BuzzExplicit) > ACP > persona > global > definition >
  file, so the panel shows the effort the next spawn launches with while
  `resolve_with_override` exposes the running ACP value as the struck-through
  override — neither masks the other silently.
- `persist_agent_effort_level` is a direct-write Tauri setter (writes
  record.effort_level + updated_at, save_managed_agents) that rejects non-local
  backends: remote effort is set at deploy time via policy_env, not here.
- EffortPickerField is the local-only write control, mounted in
  AgentInstanceEditDialog beside the model block, gated on a local backend AND
  a discovered effortConfigId. It persists directly and invalidates the config
  surface, mirroring the setManagedAgentAutoRestart standalone-setter precedent
  so the frozen UpdateManagedAgentInput shape stays frozen.
- buzz-acp applies the startup effort env at session start.

Contract notes for review:
- Picker/display split: the WRITE control lives in AgentInstanceEditDialog;
  the read-only configured-vs-current two-facts DISPLAY stays in
  AgentConfigPanel's thinkingEffort normalized field (the reader work feeds it).
- RelayMeshConfig extracted from types.rs into types/relay_mesh.rs to keep the
  grandfathered file under its size ceiling; no behavior change.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
A live model switch collapsed adapter rejection into success: apply_model_switch
returned Ok on both an accepted switch and an application-level refusal, so the
caller cached pre-switch capabilities as if they described the target model and
Desktop reported the pick as landed.

Introduce ModelSwitchOutcome::{Applied(Value),Rejected}. Transport-class errors
still propagate as Err (respawn the poisoned stdio); an application-level refusal
is now Rejected. The caller drives everything off post_switch_snapshot: Applied
refreshes model_capabilities from the target model's echoed configOptions (or
drops to None when none are echoed, so a pre-switch snapshot is never mistaken
for the target's); Rejected preserves pre-switch caps and emits a failure
control_result. Effort resolution and the session-config capture read the
post-switch snapshot so they converge on the model the session actually runs,
and modelOverridden is gated on switch_succeeded.

Switch results carry request and channel identity so a reconnect replay or a
stale result from an earlier pick can no longer settle the wrong operation, and
dispatch dedup fires side-effect listeners only for accepted (non-duplicate)
events. The busy-path switch no longer infers success from timeout silence: the
deferred apply emits a correlated positive "switched" control_result when it
lands, liveSwitchOutcome.ts resolves "ok" only from that real terminal, and the
fallback timeout resolves an honest "pending" (accepted, apply deferred) rather
than a false "ok". ModelPicker surfaces a distinct toast per outcome — failed,
unsupported, and pending.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
The live-switch outcome counted every status other than unsupported_model/
failure/sent as a positive terminal, so turn_ending and no_active_turn — which
the harness emits when the switch was NEVER delivered (control oneshot already
consumed; no in-flight task and no idle session) — resolved "ok" and toasted
"Model switched for this session." In both the desired model is never set and
nothing applies later.

Handle statuses exhaustively: only switched confirms an applied positive
terminal, sent stays provisional, turn_ending/no_active_turn fail-fast to a new
not_delivered outcome with a truthful toast, and any unknown future status is
inert rather than default-counted as success.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Fold the three separate huddle:: use statements (audio_output, reconnect,
root) into one nested use, removing a line so lib.rs stays at the file-size
ratchet ceiling after main's own churn lowered the base. Semantics-preserving.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Main grew spawn_snapshot/tests.rs's neighbors so the PR's identical +143
test delta now lands the file at 1071 lines, tripping the 1000-line
desktop file-size ratchet. Relocate the self-contained B5 single-canonical
effort block (and its two local helpers) into the sibling tests_ext.rs
already carved out for this purpose. Pure code motion, zero behavior
change; both files now sit below the ceiling.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
@wpfleger96
wpfleger96 merged commit 50a7113 into main Aug 18, 2026
31 checks passed
@wpfleger96
wpfleger96 deleted the duncan/claude-config-gaps branch August 18, 2026 20:29
mfethe1 pushed a commit to mfethe1/buzz that referenced this pull request Aug 18, 2026
Main (block#4557) reworked `processLiveObserverEvents` so the side-effect dispatch
loop iterates only the ACCEPTED events. The observer relay replays five minutes
of frames on reconnect, and re-dispatching one would let a replayed
`control_result` re-settle a live model switch. It also renamed `addedEvents`
to `accepted`.

This branch had added circuit-breaker tracking to the same function, and it
iterates the FULL envelope on purpose: `appendAgentEvents`' per-agent eviction
floor and `applyCircuitEvent`'s per-slot ordering gate compare against
different reference points, so a frame the floor rejects can still be the first
one ever seen for its circuit slot.

Taking either side wholesale destroys the other's guarantee silently -- keeping
main's loop drops legitimate circuit transitions; keeping this branch's loop
reinstates double-dispatch on replay. So the two passes are separated:

- circuit state consumes every event in the envelope. Replay is handled by
  applyCircuitEvent's own per-slot gate, not by the accepted filter.
- the side-effect listeners consume only `accepted`, unchanged from main.
- publication keeps main's targeted payload, plus this branch's circuit-only
  wake for the case where nothing was retained but the badge must repaint.

The conflict is not a side effect of the previous merge commit: `git merge-tree
origin/main 64b8dcd` conflicts too, so the original branch tip had already
been broken by block#4557 landing.

Verified in this worktree on x86_64-pc-windows-msvc:
- `pnpm exec tsc --noEmit`: clean.
- `pnpm check` (biome + file-size ratchet + px-text + pubkey guards): exit 0.
- `pnpm test`: 5045 passed, 0 failed.

Signed-off-by: Michael Feth <michael@jira-flow.com>
wpfleger96 added a commit that referenced this pull request Aug 18, 2026
#4557 mounted EffortPickerField into AgentInstanceEditDialog, which this PR
deletes. Fold the write control into the merged dialog's instance section
under the same gating (local backend + discovered effortConfigId), wiring the
agent config surface query in the parent. Preserves the direct-write path,
surface invalidation, and edit-agent-effort id unchanged.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
mfethe1 pushed a commit to mfethe1/buzz that referenced this pull request Aug 18, 2026
block#4557 ("close five Claude Code agent-config gaps") landed on main and conflicts
with this branch. Resolutions:

1. `lib.rs` deep_link import. Both sides had independently dropped the two
   standalone `use huddle::` lines; the only real difference was the glob. The
   glob stays -- it is what keeps lib.rs under the size ratchet, four other
   globs in the same file make it idiomatic, and it cannot go stale when main
   adds another deep_link symbol.

2. `lib.rs` generate_handler list. Additive on both sides: main added
   `persist_agent_effort_level`, this branch the two routing-policy commands.
   All three kept.

3. `reader.rs` config_file_path. Main extracted the logic into
   `config_file_path_for_runtime` and threaded a new `claude_config_dir`
   parameter through it, while this branch had added an OpenCode special case
   at the old call site. Taking main's side alone silently drops OpenCode
   config discovery, so the special case moved INTO main's helper -- where it
   now sits beside the `opencode` arm that already exists in the sibling
   `mcp_config_file_path_for_runtime`.

Two further defects that no textual merge could surface:

- `reader_tests_opencode.rs` did not compile. Main gave `read_config_surface`
  a fifth parameter (`claude_config_dir`); this file is new on this branch and
  untouched by main, so git merged it cleanly and the call kept passing four
  arguments. This is the third time this branch has been broken by exactly that
  shape -- a signature or struct change upstream in code the branch never
  touched.

- The preset-logo guard was asserting on itself, not on the data. This branch
  moved `KNOWN_ACP_RUNTIMES` out of `discovery.rs` into
  `discovery/known_runtimes.rs` and gave it `pub(super)` visibility, but left
  the guard reading the old path with a regex requiring a bare `const`. Both
  halves stopped matching, so it failed on `could not locate KNOWN_ACP_RUNTIMES`
  before checking anything. This was broken on the branch tip before this merge,
  not caused by it. The guard now reads the real file and tolerates an optional
  visibility modifier, so a future move cannot re-break the match the same way.

Verified in this worktree on x86_64-pc-windows-msvc:
- `cargo check --manifest-path desktop/src-tauri/Cargo.toml --all-targets`: clean
  (was error[E0061]).
- `cargo test --manifest-path desktop/src-tauri/Cargo.toml --lib`: 2450 passed,
  1 failed -- `claude_spawn_uses_the_probed_cli_executable`, which passes in
  isolation and fails the same way on clean main.
- `pnpm exec tsc --noEmit`: clean.
- `pnpm check` (biome + file-size ratchet + px-text + pubkey guards): exit 0.
- `presetLogos.test.mjs`: 11 passed (was a hard failure).

Signed-off-by: Michael Feth <michael@jira-flow.com>
wpfleger96 pushed a commit that referenced this pull request Aug 18, 2026
…c-agent-commit-identity

* origin/main:
  feat(managed-agents): close five Claude Code agent-config gaps (#4557)
  chore(hooks): keep mobile analysis out of pre-commit (#6236)
  fix(shared-ui): delay hover disclosures by default (#5821)

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
wpfleger96 added a commit that referenced this pull request Aug 18, 2026
#4557 mounted EffortPickerField into AgentInstanceEditDialog, which this PR
deletes. Fold the write control into the merged dialog's instance section
under the same gating (local backend + discovered effortConfigId), wiring the
agent config surface query in the parent. Preserves the direct-write path,
surface invalidation, and edit-agent-effort id unchanged.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
jedwards27 pushed a commit to jedwards27/buzz that referenced this pull request Aug 18, 2026
* origin/main: (43 commits)
  perf(desktop): parallelize relay agent directory rebuild (block#6258)
  Refine the mobile emoji picker (block#5853)
  fix(desktop): exclude archived agents from nest, order regeneration (block#5905)
  Add font size and conversation density preferences (block#5644)
  fix(desktop): emit camelCase config-write payload fields (block#6062)
  fix(desktop): downscale large avatars for agent-share PNG body (block#6260)
  fix(desktop): preserve early relay auth challenges (block#3320)
  Polish mobile message actions (block#5873)
  Refine mobile pairing confirmation (block#6018)
  chore(scripts): add buzz-adopt-prod-agents.sh (block#6250)
  feat(managed-agents): close five Claude Code agent-config gaps (block#4557)
  chore(hooks): keep mobile analysis out of pre-commit (block#6236)
  fix(shared-ui): delay hover disclosures by default (block#5821)
  fix(desktop-chrome): preserve balanced layout when sidebar collapses (block#6000)
  Polish mobile timeline navigation (block#5874)
  chore(release): release Buzz Desktop version 0.5.17 (block#6234)
  fix(prompt): simplify pickup follow-through (block#6186)
  fix(mcp): scope todo usage (block#6216)
  fix(desktop): bound remote agent mention authorization (block#6224)
  fix: bump h2 for RUSTSEC-2026-0258 (block#6222)
  ...

Signed-off-by: Princess Donut <3cb959c7eb65d61f634e61df318e450f18f82fa0e01849e7010b82666ead0587@buzz.block.builderlab.xyz>

# Conflicts:
#	desktop/src/main.tsx
#	mobile/ios/Podfile.lock
yjc801 added a commit to yjc801/buzz that referenced this pull request Aug 19, 2026
Resolves seven conflicts, all in the desktop managed-agent surface, where
upstream's "close five Claude Code agent-config gaps" (block#4557) and
"exclude archived agents from nest" (block#5905) landed on code the fork had
relocated to stay under the file-size ratchet:

- types.rs / types.ts / nest/tests.rs: fork had moved the conflicting
  blocks to record_views.rs, managedAgent.ts, and (upstream) render_tests.rs.
  Kept the relocated homes and ported upstream's new `effort_level` field
  into record_views.rs plus the fork's community_relay_url /
  residual_deployments / waker_enabled fields into render_tests.rs.
- readiness.rs / discovery/tests.rs: fork builds fixtures from JSON so new
  optional record fields don't churn them; kept that over upstream's
  struct literals.
- mod.rs / tauriManagedAgents.ts: both sides added declarations at the same
  spot; kept both.

The merge also pushed two files past the desktop file-size ratchet through
accumulated growth on both sides. Split them along the module's existing
seams rather than raising the limit:

- commands/agents_deploy.rs (1037 -> 536): tests moved to
  agents_deploy_tests.rs, matching the agent_config.rs idiom.
- managed_agents/runtime.rs (1003 -> 981): git credential-helper env moved
  to runtime/git_credentials.rs.

Verified: workspace clippy + fmt, Tauri clippy/fmt/tests (2650 passed),
desktop tsc/biome/tests (5169 passed)/build, desktop file-size + px-text
guards, mobile format/analyze/tests (1523 passed) + file-size guard.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Junchao Yan <yjc801@gmail.com>
wpfleger96 pushed a commit that referenced this pull request Aug 19, 2026
…-in-thread

* origin/main: (32 commits)
  Revert "fix(acp): gate relay-signed workflow messages on their attributed author" (#6311)
  fix(desktop): morph the drawer panel icon instead of sliding it (#6306)
  feat(desktop): refine repository-aware project workspaces (#6003)
  Fix mobile Activity thread navigation (#5850)
  perf(desktop): parallelize relay agent directory rebuild (#6258)
  Refine the mobile emoji picker (#5853)
  fix(desktop): exclude archived agents from nest, order regeneration (#5905)
  Add font size and conversation density preferences (#5644)
  fix(desktop): emit camelCase config-write payload fields (#6062)
  fix(desktop): downscale large avatars for agent-share PNG body (#6260)
  fix(desktop): preserve early relay auth challenges (#3320)
  Polish mobile message actions (#5873)
  Refine mobile pairing confirmation (#6018)
  chore(scripts): add buzz-adopt-prod-agents.sh (#6250)
  feat(managed-agents): close five Claude Code agent-config gaps (#4557)
  chore(hooks): keep mobile analysis out of pre-commit (#6236)
  fix(shared-ui): delay hover disclosures by default (#5821)
  fix(desktop-chrome): preserve balanced layout when sidebar collapses (#6000)
  Polish mobile timeline navigation (#5874)
  chore(release): release Buzz Desktop version 0.5.17 (#6234)
  ...

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
wpfleger96 added a commit that referenced this pull request Aug 19, 2026
#4557 mounted EffortPickerField into AgentInstanceEditDialog, which this PR
deletes. Fold the write control into the merged dialog's instance section
under the same gating (local backend + discovered effortConfigId), wiring the
agent config surface query in the parent. Preserves the direct-write path,
surface invalidation, and edit-agent-effort id unchanged.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
wpfleger96 pushed a commit that referenced this pull request Aug 19, 2026
…ntion-phase1

* origin/main: (71 commits)
  Revert "fix(acp): gate relay-signed workflow messages on their attributed author" (#6311)
  fix(desktop): morph the drawer panel icon instead of sliding it (#6306)
  feat(desktop): refine repository-aware project workspaces (#6003)
  Fix mobile Activity thread navigation (#5850)
  perf(desktop): parallelize relay agent directory rebuild (#6258)
  Refine the mobile emoji picker (#5853)
  fix(desktop): exclude archived agents from nest, order regeneration (#5905)
  Add font size and conversation density preferences (#5644)
  fix(desktop): emit camelCase config-write payload fields (#6062)
  fix(desktop): downscale large avatars for agent-share PNG body (#6260)
  fix(desktop): preserve early relay auth challenges (#3320)
  Polish mobile message actions (#5873)
  Refine mobile pairing confirmation (#6018)
  chore(scripts): add buzz-adopt-prod-agents.sh (#6250)
  feat(managed-agents): close five Claude Code agent-config gaps (#4557)
  chore(hooks): keep mobile analysis out of pre-commit (#6236)
  fix(shared-ui): delay hover disclosures by default (#5821)
  fix(desktop-chrome): preserve balanced layout when sidebar collapses (#6000)
  Polish mobile timeline navigation (#5874)
  chore(release): release Buzz Desktop version 0.5.17 (#6234)
  ...

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
mfethe1 pushed a commit to mfethe1/buzz that referenced this pull request Aug 21, 2026
block#4557 ("close five Claude Code agent-config gaps") landed on main and conflicts
with this branch. Resolutions:

1. `lib.rs` deep_link import. Both sides had independently dropped the two
   standalone `use huddle::` lines; the only real difference was the glob. The
   glob stays -- it is what keeps lib.rs under the size ratchet, four other
   globs in the same file make it idiomatic, and it cannot go stale when main
   adds another deep_link symbol.

2. `lib.rs` generate_handler list. Additive on both sides: main added
   `persist_agent_effort_level`, this branch the two routing-policy commands.
   All three kept.

3. `reader.rs` config_file_path. Main extracted the logic into
   `config_file_path_for_runtime` and threaded a new `claude_config_dir`
   parameter through it, while this branch had added an OpenCode special case
   at the old call site. Taking main's side alone silently drops OpenCode
   config discovery, so the special case moved INTO main's helper -- where it
   now sits beside the `opencode` arm that already exists in the sibling
   `mcp_config_file_path_for_runtime`.

Two further defects that no textual merge could surface:

- `reader_tests_opencode.rs` did not compile. Main gave `read_config_surface`
  a fifth parameter (`claude_config_dir`); this file is new on this branch and
  untouched by main, so git merged it cleanly and the call kept passing four
  arguments. This is the third time this branch has been broken by exactly that
  shape -- a signature or struct change upstream in code the branch never
  touched.

- The preset-logo guard was asserting on itself, not on the data. This branch
  moved `KNOWN_ACP_RUNTIMES` out of `discovery.rs` into
  `discovery/known_runtimes.rs` and gave it `pub(super)` visibility, but left
  the guard reading the old path with a regex requiring a bare `const`. Both
  halves stopped matching, so it failed on `could not locate KNOWN_ACP_RUNTIMES`
  before checking anything. This was broken on the branch tip before this merge,
  not caused by it. The guard now reads the real file and tolerates an optional
  visibility modifier, so a future move cannot re-break the match the same way.

Verified in this worktree on x86_64-pc-windows-msvc:
- `cargo check --manifest-path desktop/src-tauri/Cargo.toml --all-targets`: clean
  (was error[E0061]).
- `cargo test --manifest-path desktop/src-tauri/Cargo.toml --lib`: 2450 passed,
  1 failed -- `claude_spawn_uses_the_probed_cli_executable`, which passes in
  isolation and fails the same way on clean main.
- `pnpm exec tsc --noEmit`: clean.
- `pnpm check` (biome + file-size ratchet + px-text + pubkey guards): exit 0.
- `presetLogos.test.mjs`: 11 passed (was a hard failure).

Signed-off-by: Michael Feth <michael@jira-flow.com>
kaalph pushed a commit to kaalph/buzz that referenced this pull request Aug 21, 2026
…k#4938)

Add the Auto variant to PermissionMode (wire string 'auto'; block#4557 adds the
same variant from the claude-config arc — this commit establishes the
contradiction logic ahead of that merge so the rebase is mechanical).

Auto mode = fully autonomous execution; model-gated (requires
supportsAutoMode); the adapter self-approves all tool calls internally
and never emits session/request_permission.

Mode matrix:
- allow + auto → compatible (transmit as-is; both want unattended approval)
- ask   + auto → startup error (card never fires — ask becomes a dead letter)
- reject + auto → startup error (inverted-security worst case: policy says
                  deny while adapter silently auto-approves everything)

Tests: 4 new pinned tests (allow+auto ok, ask+auto error, reject+auto error,
wire string correct). Total: 724 passing.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Claude Code agents ignore the model set in Buzz Desktop — model picker persists but nothing applies it at spawn

2 participants